package com.atguigu.day11.ploy.p3;

/*
人 养 动物
开闭原则:
   开:对功能的拓展是开放的
   闭:对源码的修改是关闭的
多态: 同一个行为 不同的对象有不同的展示能力
  作用:简化代码 提高代码的复用性
  语法:
     向上转型:
         前提:有继承关系
              有方法重写
              有父类的引用 指向子类的实例(对象)
                父亲           孩子
               Animal a = new Dog();
         向上转型后对象的(a)方法调用:
               编译(javac 写完代码后)看父亲:
                  可以调用父类Animal中所有的方法
               运行(java 点击运行按钮后)看孩子:
                如果重写了  调用子类重写父类的方法
                如果没有重写 调用从父类继承的方法
         应用:
            应用在数组  父类类型做数组类型 可以存储任意子类对象
            应用在返回值类型 父类类型做返回值类型 可以返回任意子类对象
            应用在形参  父类类型做形参 可以接收任意子类对象
         注意:
            1.向上转型后 无法使用子类新增(独有)的方法
     向下转型: 已经完成了向上转型 还想使用子类独有方法
         语法: 子类类型 对象名 = (子类类型)父类类型的值;
           double d = 100;
         问题: 类型转换异常
         解决: 对象 instanceof 类型 判断左边的对象是否属于右边的类型
               只要对象在 类型的继承关系上就会返回true
 */
public class Test {

    public static void main(String[] args) {
        Dog d = new Dog();
        Cat c = new Cat();
      /*  double d2 = 100;
        int i = (int)d2;*/

        showEat(d);
        showEat(c);

    }
    /*
    向上
         Animal a = new Cat()
     */
    public static void showEat(Animal a) {
        a.eat();
        /*
          a instanceof Cat c
            1.判断 a对象是否为Cat 类型
            2.如果是则内部完成向下转型 转型后的对象名是 c

            对象 instanceof 类型 判断左边的对象是否属于右边的类型
            只要对象在 类型的继承关系上就会返回true
        */
        if(a instanceof Cat c){
            c.catchMouse();
        }
        if(a instanceof Dog d){
            d.lookHome();
        }
    }

    public static void showEat2(Animal a) {
        a.eat();

        if (a instanceof Cat) {
            //todo  子类类型 对象名 = (子类类型)父类类型的值;
            Cat c = (Cat) a;
            c.catchMouse();
        }

        if (a instanceof Dog) {
            Dog d = (Dog) a;
            d.lookHome();
        }

    }

}
